1 module hip.filesystem.systems.cstd; 2 import hip.api.filesystem.hipfs; 3 4 5 /** 6 * All those string allocations should be removed or turnt into @nogc somehow. The better cached, the best. 7 * 8 */ 9 class HipCStdioFileSystemInteraction : IHipFileSystemInteraction 10 { 11 version(Windows) 12 pragma(lib, "Shlwapi.lib"); //PathIsDirectory 13 bool read(string path, void delegate(ubyte[] data) onSuccess, void delegate(string err) onError) 14 { 15 import core.stdc.stdio; 16 import hip.error.handler; 17 import hip.util.conv; 18 if(ErrorHandler.assertLazyErrorMessage(exists(path), "FileSystem Error:", "Filed named '"~path~"' does not exists")) 19 return false; 20 21 auto f = fopen((path~"\0").ptr, "rb"); 22 if(f is null) 23 { 24 onError("File not found."); 25 return false; 26 } 27 if(fseek(f, 0, SEEK_END)) 28 { 29 fclose(f); 30 onError("Could not seek to file end."); 31 return false; 32 } 33 auto size = ftell(f); 34 35 if(size <= 0) 36 { 37 fclose(f); 38 onError("Size <= 0 on file "~path); 39 return false; 40 } 41 if(fseek(f, 0, SEEK_SET)) 42 { 43 fclose(f); 44 onError("Could not seek to file beginning"); 45 return false; 46 } 47 ubyte[] output = new ubyte[size]; 48 49 if(size_t readed = fread(cast(void*)output.ptr, 1, cast(size_t)size, f) != size) 50 { 51 fclose(f); 52 onError("File is corrupted. Could not read file entirely (Readed "~to!string(readed)~") Expected "~to!string(size)); 53 return false; 54 } 55 fclose(f); 56 onSuccess(output); 57 return true; 58 } 59 bool write(string path, void[] data) 60 { 61 import core.stdc.stdio; 62 if(exists(path)) 63 { 64 auto file = fopen(cachedStringz(path), "w"); 65 scope(exit) 66 fclose(file); 67 if(fwrite(data.ptr, 1, data.length, file) != data.length) 68 { 69 return fflush(file) == 0; 70 } 71 return true; 72 } 73 return false; 74 } 75 bool exists(string path) 76 { 77 import core.stdc.stdio; 78 if(auto file = fopen(cachedStringz(path), "r")) 79 { 80 fclose(file); 81 return true; 82 } 83 return false; 84 } 85 bool remove(string path) 86 { 87 static import core.stdc.stdio; 88 if(exists(path)) 89 { 90 return core.stdc.stdio.remove(cachedStringz(path)) == 0; 91 } 92 93 return false; 94 } 95 version(Posix) 96 import core.sys.posix.sys.stat; 97 else version(Windows) 98 import core.sys.windows.shlwapi : PathIsDirectoryA; 99 bool isDir(string path) 100 { 101 version(Windows) 102 { 103 return PathIsDirectoryA(cachedStringz(path)) == 1; 104 } 105 else version(Posix) 106 { 107 stat_t st; 108 stat(cachedStringz(path), &st); 109 return S_ISDIR(st.st_mode); 110 } 111 else return path[$-1] == '/'; 112 } 113 114 }